package role

import (
	"context"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/errcode"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/permission"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/role"
	userRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	"git.myscrm.cn/golang/stark/v4"
)

type roleService struct {
	roleRepo       role.RoleRepositoryIface
	permissionRepo permission.PermissionRepositoryIface
	userRoleRepo   userRepo.UserRoleRepositoryIface
}

// NewRoleService 构造函数
func NewRoleService(
	roleRepo role.RoleRepositoryIface,
	permissionRepo permission.PermissionRepositoryIface,
	userRoleRepo userRepo.UserRoleRepositoryIface,
) RoleServiceIface {
	return &roleService{
		roleRepo:       roleRepo,
		permissionRepo: permissionRepo,
		userRoleRepo:   userRoleRepo,
	}
}

// AddPermissionsToRole 角色增加权限
func (s *roleService) AddPermissionsToRole(ctx context.Context, roleId int64, perIds []int64) error {
	roleDetail, err := s.roleRepo.RoleDetail(ctx, roleId)
	if err != nil {
		return err
	}

	if (roleDetail == nil) || (roleDetail.Id == 0) {
		return errcode.RoleDataNotExist
	}

	perList, err := s.permissionRepo.PermissionListByIds(ctx, perIds)
	if err != nil {
		return err
	}

	if len(perIds) != len(perList) {
		return errcode.RoleDataNotExist
	}

	err = s.roleRepo.AddPermissionToRole(ctx, roleId, perIds)
	stark.Logger.Infof(ctx, "AddPermissionsToRole-info, role_id: %d, per_ids: %+v, err: %+v", roleId, perIds, err)
	return err
}

// RoleSave 新增/更新角色
func (s *roleService) RoleSave(ctx context.Context, role *role.GfyRolePo) (int64, error) {
	// 1. 检查名称是否存在
	cRole, err := s.roleRepo.GetByRoleName(ctx, role.Name)
	if err != nil {
		return 0, err
	}
	if cRole.Id != 0 && cRole.Id != role.Id {
		return 0, errcode.RoleNameExist
	}

	// 2. 保存角色信息
	roleId, err := s.roleRepo.RoleSave(ctx, role)
	stark.Logger.Infof(ctx, "RoleSave-info, role: %+v, err: %+v", role, err)

	return roleId, err
}

// DeleteRole 删除角色
func (s *roleService) DeleteRole(ctx context.Context, roleId int64, operatorId int64) (int64, error) {
	// 1. 检查角色是否有人在用
	userRoleList, err := s.userRoleRepo.GetUsersByRoleId(ctx, roleId)
	if err != nil {
		return 0, err
	}
	if len(userRoleList) != 0 {
		return 0, errcode.RoleUsingErr
	}

	id, err := s.roleRepo.DeleteRole(ctx, roleId, operatorId)
	stark.Logger.Infof(ctx, "DeleteRole-info, role_id: %d, operatorId: %d, err: %+v", roleId, operatorId, err)
	return id, err
}

// RoleList 角色列表
func (s *roleService) RoleList(ctx context.Context) ([]*role.GfyRolePo, error) {
	return s.roleRepo.RoleList(ctx)
}

// RolePermissionList 根据角色获取权限列表
func (s *roleService) RolePermissionList(ctx context.Context, roleId int64) ([]*permission.GfyxPermission, error) {
	permissionList := make([]*permission.GfyxPermission, 0)
	rolePerList, err := s.roleRepo.PermissionListByRoleId(ctx, roleId)
	if err != nil {
		return nil, err
	}

	if len(rolePerList) == 0 {
		return permissionList, nil
	}

	perIds := make([]int64, 0)
	for _, p := range rolePerList {
		perIds = append(perIds, p.PermissionId)
	}

	return s.permissionRepo.PermissionListByIds(ctx, perIds)
}
